/* ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   Module Name          : com.yaodian100.crm.logistic.remote.RemoteUserServiceImpl
   Module Description   :

   Date Created      : 2011/4/28
   Original Author   : cut7man
   Team              : yaodian100
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
   MODIFICATION HISTORY
   ------------------------------------------------------------------------------
   Date Modified       Modified by       Comments
   ------------------------------------------------------------------------------
   ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
package com.yaodian100.crm.logistic.remote;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.RecoverableDataAccessException;
import org.springframework.security.userdetails.UserDetails;
import org.springframework.security.userdetails.UsernameNotFoundException;

import com.yaodian100.core.admin.entity.User;
import com.yaodian100.core.admin.entity.UserPermission;
import com.yaodian100.core.admin.service.UserService;
import com.yaodian100.core.common.exception.CoreException;
import com.yaodian100.core.common.service.BaseManager;
import com.yaodian100.core.menu.entity.Menu;
import com.yaodian100.core.menu.service.MenuService;
import com.yaodian100.crm.logistic.entity.ChangePwdLog;

/**
 * @author cut7man
 * 
 */
public class RemoteUserServiceImpl implements RemoteUserService {
	private UserService userService;
	private BaseManager baseMgr;
	private MenuService menuService;

	/**
	 * @return the userService
	 */
	public UserService getUserService() {
		return userService;
	}

	/**
	 * @param userService the userService to set
	 */
	public void setUserService(UserService userService) {
		this.userService = userService;
	}

	/**
	 * @return the baseMgr
	 */
	public BaseManager getBaseMgr() {
		return baseMgr;
	}

	/**
	 * @param baseMgr the baseMgr to set
	 */
	public void setBaseMgr(BaseManager baseMgr) {
		this.baseMgr = baseMgr;
	}

	/**
	 * @return the menuService
	 */
	public MenuService getMenuService() {
		return menuService;
	}

	/**
	 * @param menuService the menuService to set
	 */
	public void setMenuService(MenuService menuService) {
		this.menuService = menuService;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.crm.logistic.remote.RemoteUserService#changePwd()
	 */
	@Override
	public String changePwd(String username, String oldPassword, String newPassword) {
		try {
			User user = userService.get(username);
			ChangePwdLog cpl = (ChangePwdLog) baseMgr.get(ChangePwdLog.class, user.getUsername());
			cpl.setChangeDate(new Date());
			baseMgr.update(cpl);
			userService.changePassword(user, newPassword, oldPassword);
			return ("密码变更成功");
		} catch (CoreException e) {
			e.printStackTrace();
			if ("errors.account.password".equals(e.getMessage())) {
				return ("密码错误");
			} else {

				return e.getLocalizedMessage();
			}

		} catch (Exception e) {
			e.printStackTrace();
			return e.getLocalizedMessage();

		}
	}

	public User[] toUnlock() {

		Object[] theCpls = baseMgr.queryByHql("from ChangePwdLog", null);
		List<String> usernames = new ArrayList<String>();
		if (theCpls != null) {
			for (Object obj : theCpls) {
				ChangePwdLog cpl = (ChangePwdLog) obj;
				usernames.add(cpl.getUsername());
			}
		}

		DetachedCriteria dc = DetachedCriteria.forClass(User.class);
		dc.add(Restrictions.eq("status", "0"));
		if (usernames != null && usernames.size() > 0) {
			dc.add(Restrictions.in("username", usernames));
		}
		Object[] users = baseMgr.findByCriteria(dc);
		User[] theUsers = null;
		if (users != null && users.length > 0) {
			theUsers = new User[users.length];

			for (int i = 0; i < users.length; i++) {
				theUsers[i] = (User) users[i];
			}

		}
		return theUsers;
		// RemoteUser[] rUsers = null;
		// if (users != null && users.length > 0) {
		// rUsers = new RemoteUser[users.length];
		// }
		// if (users != null) {
		// for (int i = 0; i < users.length; i++) {
		//
		// User user = (User) users[i];
		//
		// RemoteUser ru = new RemoteUser();
		// ru.setUsername(user.getUsername());
		// ru.setAccountNonExpired(true);
		// ru.setAccountNonLocked(true);
		// Object[] userPermissions = baseMgr.queryByHql("from UserPermission where user.username=?", new Object[] { user
		// .getUsername() });
		//
		// GrantedAuthorityImpl[] auths = new GrantedAuthorityImpl[userPermissions.length];
		// for (int j = 0; j < userPermissions.length; j++) {
		// UserPermission up = (UserPermission) userPermissions[j];
		// GrantedAuthorityImpl g = new GrantedAuthorityImpl();
		// g.setAuthority(up.getAuthority());
		//
		// auths[j] = g;
		// // Permission p=(Permission)baseMgr.get(Permission.class, up.getAuthority())
		// }
		//
		// ru.setAuthorities(auths);
		// // ru.setCreateDate(user.getCreateDate());
		// // ru.setCreateUser(user.getCreateUser());
		// ru.setCredentialsNonExpired(true);
		// ru.setEmail(user.getEmail());
		// ru.setErrorCount(user.getErrorCount());
		// ru.setGroupDescription(user.getGroup().getDescription());
		// ru.setGroupName(user.getGroupName());
		// ru.setLang(user.getLang());
		// ru.setLoginIP(user.getLoginIP());
		// ru.setMobile(user.getMobile());
		// // ru.setModifyUser(user.getModifyUser());
		// ru.setNameFirst(user.getNameFirst());
		// ru.setNameLast(user.getNameLast());
		// ru.setNameNative(user.getNameNative());
		// ru.setNameNick(user.getNameNick());
		// ru.setNeedChangePassword(false);
		// ru.setPassword(user.getPassword());
		// ru.setPhone(user.getPhone());
		// ru.setStatus(user.getStatus());
		// ru.setUsername(user.getUsername());
		// ru.setGroupDescription(user.getGroup().getDescription());
		// rUsers[i] = ru;
		// }
		// }
		// return rUsers;
	}

	public void unlock(String username) {
		User user = (User) baseMgr.get(User.class, username);
		ChangePwdLog cpl = (ChangePwdLog) baseMgr.get(ChangePwdLog.class, username);
		if (cpl == null) {
			cpl = new ChangePwdLog();
		}
		cpl.setUsername(username);
		user.setStatus("9");
		baseMgr.update(user);
		cpl.setChangeDate(new Date());
		baseMgr.update(cpl);

	}

	public Menu userStatus() {
		Menu menu = menuService.get("User.status");
		return menu;
		// if (menu != null && menu.getOptions() != null) {
		// RemoteOption[] ros = new RemoteOption[menu.getOptions().size()];
		// int i = 0;
		// for (Option option : menu.getOptions().values()) {
		// RemoteOption ro = new RemoteOption();
		// BeanUtils.copyProperties(option, ro);
		// ro.setMenuKey(menu.getKey());
		// ros[i] = ro;
		// i++;
		// }
		// return ros;
		// }
		// return null;
	}

	public User getUser(String username) {
		User user = (User) baseMgr.get(User.class, username);
		return user;
		// if (user == null) {
		// return null;
		// }
		// RemoteUser ru = new RemoteUser();
		// ru.setUsername(user.getUsername());
		// ru.setAccountNonExpired(true);
		// ru.setAccountNonLocked(true);
		// Object[] userPermissions = baseMgr.queryByHql("from UserPermission where user.username=?",
		// new Object[] { username });
		//
		// GrantedAuthority[] auths = new GrantedAuthority[userPermissions.length];
		// for (int i = 0; i < userPermissions.length; i++) {
		// UserPermission up = (UserPermission) userPermissions[i];
		// auths[i] = up;
		// // Permission p=(Permission)baseMgr.get(Permission.class, up.getAuthority())
		// }
		//
		// ru.setAuthorities(auths);
		// // ru.setCreateDate(user.getCreateDate());
		// // ru.setCreateUser(user.getCreateUser());
		// ru.setCredentialsNonExpired(true);
		// ru.setEmail(user.getEmail());
		// ru.setErrorCount(user.getErrorCount());
		// ru.setGroupDescription(user.getGroup().getDescription());
		// ru.setGroupName(user.getGroupName());
		// ru.setLang(user.getLang());
		// ru.setLoginIP(user.getLoginIP());
		// ru.setMobile(user.getMobile());
		// // ru.setModifyUser(user.getModifyUser());
		// ru.setNameFirst(user.getNameFirst());
		// ru.setNameLast(user.getNameLast());
		// ru.setNameNative(user.getNameNative());
		// ru.setNameNick(user.getNameNick());
		// ru.setNeedChangePassword(false);
		// ru.setPassword(user.getPassword());
		// ru.setPhone(user.getPhone());
		// ru.setStatus(user.getStatus());
		// ru.setUsername(user.getUsername());
		// return ru;
	}

	public boolean validatePassword(User ruser, String password) throws CoreException {
		User user = (User) baseMgr.get(User.class, ruser.getUsername());
		return userService.validatePassword(user, password);
	}

	public void save(User user) {

		User u = (User) baseMgr.get(User.class, user.getUsername());
		u.setEmail(user.getEmail());
		u.setMobile(user.getMobile());
		u.setNameNative(user.getNameNative());
		u.setPhone(user.getPhone());
		baseMgr.update(u);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.springframework.security.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
	 */
	@Override
	public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException, DataAccessException {
		UserDetails entity = null;
		try {
			// entity = getUser(username);
			User user = (User) baseMgr.get(User.class, username);
			RemoteUserDetail rud = new RemoteUserDetail(username);
			Object[] userPermissions = baseMgr.queryByHql("from UserPermission where user.username=?",
					new Object[] { username });

			GrantedAuthorityImpl[] auths = new GrantedAuthorityImpl[userPermissions.length];
			for (int j = 0; j < userPermissions.length; j++) {
				UserPermission up = (UserPermission) userPermissions[j];
				GrantedAuthorityImpl g = new GrantedAuthorityImpl();
				g.setAuthority(up.getAuthority());

				auths[j] = g;
				// Permission p=(Permission)baseMgr.get(Permission.class, up.getAuthority())
			}
			rud.setAuthorities(auths);
			rud.setCreateDate(user.getCreateDate());
			rud.setCreateUser(user.getCreateUser());
			rud.setModifyUser(user.getModifyUser());
			rud.setPassword(user.getPassword());
			rud.setUsername(user.getUsername());
			return rud;
		} catch (CoreException e) {
			e.printStackTrace();
			throw new RecoverableDataAccessException(e.getMessage());
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.yaodian100.crm.logistic.remote.RemoteUserService#changeDate(java.lang.String)
	 */
	@Override
	public Date changeDate(String username) {
		ChangePwdLog cpl = (ChangePwdLog) baseMgr.get(ChangePwdLog.class, username);
		if (cpl != null) {
			return cpl.getChangeDate();
		} else {
			return null;
		}
	}
}
